package com.mybooksystem.springboot.service;

import com.mybooksystem.springboot.Dao.StudentInfoMapper;
import com.mybooksystem.springboot.Dao.TabDao;
import com.mybooksystem.springboot.pojo.StudentAndSubjectScore;
import com.mybooksystem.springboot.pojo.student.Students;
import com.mybooksystem.springboot.pojo.student.StudentsScoreForOneSubjects;
import com.mybooksystem.springboot.pojo.subjects.ClassNameAndSubjectsScore;
import com.mybooksystem.springboot.pojo.visualize.classForAll.StudentDataFormClassForAll;
import com.mybooksystem.springboot.pojo.visualize.classForOne.StudentDataFormClassForOne;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 学生信息的 service层。
 */
@Service
public class StudentsService {

    /**
     * 入学类型.
     */
    private final String[] admissionType = {"高考","学考","3+2","成考"};

    /**
     *
     */
    private final SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 就读类型.
     */
    private final String[] studyType ={"全日制","非全日制"};
    /**
     * 最高学历.
     */
    private final String[] educationDegree = {"专科","本科","研究生","硕士","博士"};
    /**
     * 政治面貌.
     */
    private final String[] politicalStatus={"群众","党员"};

    @Autowired
    private TabDao tabDao;
    /**
     * 学生信息的 mapper。
     */
    @Autowired
    private StudentInfoMapper studentInfoMapper;

    /**
     * 默认是 10行数据。
     * @return
     */
    public List<Students> getStudentInfoList() {

        System.out.println("学生表：");
//        tabDao.getStudentsTab(0,10).forEach(System.out::println);
//        List<Students> studentsTab = tabDao.getStudentsTab(20);
//        List<Student_grade> student_gradeTab = tabDao.getStudent_gradeTab(20);
        List<Students> students = tabDao.getStudentsInfo(10);
        students.forEach(System.out::println);


//        System.out.println("学生成绩表：");
//        tabDao.getStudent_gradeTab(0,10).forEach(System.out::println);
        return students;
    }

    /**
     * 获取前 n 条学生信息。
     * @param classId:    班级名称
     * @param studentNumber 前n条记录
     * @return
     *      查询到的记录。
     */
    public List<Students> getStudentInfoList(String classId,Integer studentNumber) {
        // 3. 进行班级信息处理。24190101 ==> 24，190101
//        String proId = "24";
//        System.out.println("classId: -->" + classId);
//        System.out.println(classId.substring(0,2));
//        String proId = classId.substring(0, 2);
//        classId = classId.substring(2);
//        System.out.println("切割数组1：" + proId);
//        System.out.println("切割数组2：" + classId);
        System.out.println();
        // 3. 进行班级信息处理。24190101 ==> 24，190101
        return studentInfoMapper.getStudentsInfo(classId.substring(0, 2),classId.substring(2),studentNumber);
    }


    /**
     * 获取所有的学生信息。
     * @return
     *
     */
    public List<Students> getAllStudentInfoList(){
        // 获取所有学生的信息。
        return studentInfoMapper.getAllStudentsInfo();

    }

    /**
     * 根据id删除学生信息。
     * @param stuId
     * @return
     */
    public void deleteStudentInfo(String stuId) {
        studentInfoMapper.deleteStudentInfo(stuId);
    }

    /**
     * 添加学生信息。
     * @param students 传进来的学生对象。
     * @return
     *      true； 添加成功。
     *      false：添加失败。
     */
    public Boolean addStudentInfo(Students students){
        return studentInfoMapper.addStudentInfo(students);
    }

    /**
     * 根据学号查询该学生是否存在。
     * @param studentId：学号
     * @return
     *      true：查询到。
     *      false：不存在。
     */
    public Boolean isStudentInfo(String studentId) {
        String studentInfo = studentInfoMapper.isStudentInfo(studentId);
        if (studentInfo != null) {
            return studentInfo.equals(studentId);
        }
        return false;
    }
    /**
     * 根据 课程id 查询是否存在。
     * @param courseID：课程号
     * @return
     *      true：查询到。
     *      false：不存在。
     */
    public Boolean isCourseID(String courseID) {
        String courseId = studentInfoMapper.isCourseID(courseID);
        if (courseId != null) {
            return courseId.equals(courseID);
        }
        return false;
    }

    /**
     * 根据 学号 查询学生信息。
     *
     * @param studentId：要查询的学生的学号。
     * @return
     *     查询到的学生信息。
     *     null：没查到。
     */
    public Students getStudentInfo(String studentId){
        return studentInfoMapper.getStudentInfo(studentId);
    }

    /**
     * 根据参数信息，进行修改学生信息。
     * @param students ： 要修改的学生对象。
     * @return
     *      true：修改成功。
     *      false：修改失败。
     */
    public Boolean updateStudentInfo(Students students) {
        // 进行类型的转换。
        //
        System.out.println("students = " + students);
        // 入学类型。【0：高考。  1：学考。   2：3+2。  成考：3】
        System.out.println("students.getAdmissionType() = " + students.getAdmissionType());
        students.setAdmissionType(admissionType[Integer.parseInt(students.getAdmissionType())]);
        // 入学时间。
        System.out.println("students.getAdmissionDate() = " + students.getAdmissionDate());

        // 就读类型。【0：全日制。1：非全日制】
        System.out.println("students.getStudyType() = " + students.getStudyType());
        students.setStudyType(studyType[Integer.parseInt(students.getStudyType())]);
        // 最高学历。【0：专科。  1：本科。   2：研究生。  3：硕士。   4：博士。】
        System.out.println("students.getEducationDegree() = " + students.getEducationDegree());
        students.setEducationDegree(educationDegree[Integer.parseInt(students.getEducationDegree())]);
        // 政治面貌。【0:群众。  1：党员。】
        System.out.println("students.getPoliticalStatus() = " + students.getPoliticalStatus());
        students.setPoliticalStatus(politicalStatus[Integer.parseInt(students.getPoliticalStatus())]);

        System.out.println("赋值之后 ====================");
        System.out.println("students = " + students);
        return studentInfoMapper.updateStudentInfo(students);
    }

    /**
     * 根据 班级编号 获取前 n 条学生分数信息的列表。
     * @param classId：      要查询的班级编号。
     * @param studentNumber：获取的开始行数。
     * @return
     *      返回学生列表。
     *      找不到返回 null。
     */
    public List<StudentAndSubjectScore> getStudentInfoListForScore(String classId, Integer studentNumber) {

        // 获取学生学号成绩表信息。
        // 初始化视图，
//        studentInfoMapper.getStudentsScoreList(studentNumber);


        // 1. 获取学号。
        // 根据专业和班级编号，获取该班级的学生分数信息。
        List<StudentDataFormClassForOne> studentScoreInfo = studentInfoMapper.getStudentScoreInfo(classId.substring(0, 2), classId.substring(2));
        studentScoreInfo.forEach(System.out::println);

        // 2. 获取当前专业的课程数。
        Integer classNumber = studentInfoMapper.getClassNumber(classId.substring(0, 2));
        System.out.println("classNumber = " + classNumber);

        StudentAndSubjectScore studentAndSubjectScore = null;
        List<Float> subjects = new ArrayList<>();
        // 定义列表容器。
        List<StudentAndSubjectScore> list = new ArrayList<>();

        // 3. 进行遍历、并进行赋值。
        int j = 0;
        String thisStudentId = studentScoreInfo.get(0).getStudentId();

//        for (int i = 0; i < studentScoreInfo.size(); i++) {
        for (int i = 0; i < studentScoreInfo.size();) {
            System.out.println("新一次遍历 i的值：" + i+"=============================");
            // 寻找同一个学生的分数。
            for (j = 0; j < classNumber+1; j++) {

                try {
                    System.out.println("当前学生学号："+studentScoreInfo.get(i+j).getStudentId());
                    // 学号相同。
                    if ( thisStudentId.equals(studentScoreInfo.get(i+j).getStudentId()) ){
                        // 添加分数。
                        subjects.add(studentScoreInfo.get(i+j).getSubjectsScore());
                    }
                    // 学号不同。
                    else {
                        thisStudentId = studentScoreInfo.get(i+j).getStudentId();
                        break;
                    }
                }catch (IndexOutOfBoundsException e){
                    System.out.println("数组越界！！！");
                    break;
                }

            }

            System.out.println("i 的值：（下标）" + i);
            // 赋值。
            studentAndSubjectScore = new StudentAndSubjectScore(
                    studentScoreInfo.get(i).getStudentId(),
                    studentScoreInfo.get(i).getStudentName(),
                    studentScoreInfo.get(i).getClassName(),
                    subjects
            );
            subjects = new ArrayList<>();
            // 添加到结果集。
            list.add(studentAndSubjectScore);
            i += j;
            System.out.println("i 的值：" + i);
            System.out.println("i+j 的值：" + (i+j));

        }

        // 4. 返回值
        System.out.println("学生分数情况：==================================");
//        System.out.println(list);
        list.forEach(System.out::println);




//        /******************************************** 旧数据 ******************************************/
//        StudentAndSubjectScore studentAndSubjectScore = null;
//        // 定义列表容器。
//        List<StudentAndSubjectScore> list = new ArrayList<>();
//        // 获取学生学号和姓名
//        List<Map<String, String>> studentIdAndStudentName = studentInfoMapper.getStudentIdAndStudentNameForClassId(classId.substring(0,2),classId.substring(2),studentNumber);
//        System.out.println("获取的学号和姓名 =================");
//        studentIdAndStudentName.forEach(System.out::println);
//        int i =0;
//        System.out.println("当前学号："+studentIdAndStudentName.get(0).get("studentId"));
//        System.out.println("当前学号："+studentIdAndStudentName.get(1).get("studentId"));
//        System.out.println("当前学号："+studentIdAndStudentName.get(2).get("studentId"));
//
//
//        for (Map<String, String> stringStringMap : studentIdAndStudentName) {
//            System.out.println("stringStringMap = " + stringStringMap);
//            System.out.println("学号：" + stringStringMap.get("studentId"));
////            List<ClassNameAndSubjectsScore> studentAllSubjectsScore = studentInfoMapper.getStudentAllSubjectsScore(String.valueOf(15112542555L));   // 可以获取数据。
//            List<ClassNameAndSubjectsScore> studentAllSubjectsScore = studentInfoMapper.getStudentAllSubjectsScore(stringStringMap.get("studentId")); // 不能获取数据。
//
//
//            System.out.println("分数：");
//            studentAllSubjectsScore.forEach(System.out::println);
////            System.out.println("获取第一个对象："+studentAllSubjectsScore.get(0));
////            System.out.println("获取第二个对象："+studentAllSubjectsScore.get(1));
////            System.out.println("获取分数："+studentAllSubjectsScore.get(0).getSubjectsScore());
//
////            List<ClassNameAndSubjectsScore> studentAllSubjectsScore = studentInfoMapper.getStudentAllSubjectsScore();
////            System.out.println("课程名和分数：" + studentAllSubjectsScore.get(0));
////            System.out.println("分数：" + studentAllSubjectsScore.get(0).getSubjectsScore());
//                // 把全部数据封装到一个对象，进行回传。
//
//            try {
//                studentAndSubjectScore = new StudentAndSubjectScore(
//                        stringStringMap.get("studentId"), stringStringMap.get("studentName"),
//                        "物联网应用技术",    /*学号，姓名，班级名称*/
//                        studentAllSubjectsScore.get(0).getSubjectsScore(),
//                        studentAllSubjectsScore.get(1).getSubjectsScore(),
//                        studentAllSubjectsScore.get(2).getSubjectsScore(),
//                        studentAllSubjectsScore.get(3).getSubjectsScore(),
//                        studentAllSubjectsScore.get(4).getSubjectsScore(),
//                        studentAllSubjectsScore.get(5).getSubjectsScore(),
//                        studentAllSubjectsScore.get(6).getSubjectsScore(),
//                        studentAllSubjectsScore.get(7).getSubjectsScore()
//                );
//            } catch (Exception e) {
//                System.out.println("没有该学生的分数信息：");
//                studentAndSubjectScore = new StudentAndSubjectScore(
//                        stringStringMap.get("studentId"), stringStringMap.get("studentName"),
//                        "物联网应用技术"    /*学号，姓名，班级名称*/
//                );
//            }
//            list.add(studentAndSubjectScore);
//        }
//        System.out.println();
//
//        // 查看该学生所在的班级名或班级编号。
//        // 根据学号获取学生的课程号和课程分数。
//        List<ClassNameAndSubjectsScore> studentAllSubjectsScore = studentInfoMapper.getStudentAllSubjectsScore(String.valueOf(100001));
//        System.out.println("获取课程名和分数 =======================");
//        studentAllSubjectsScore.forEach(System.out::println);
////        for(Map.Entry<String, Float> entry : studentAllSubjectsScore.entrySet()){
////            System.out.println(entry.getKey()+" : "+entry.getValue());
////        }
//        System.out.println();
//
////        list.forEach(System.out::println);
//
//        System.out.println("执行完毕 ===============================");
////        return studentInfoMapper.getStudentInfoListForScore(studentNumber);
//        return list;
        return list;
    }

    /**
     * 根据 班级名称，获取班级id。
     * @param className：要查询的班级名称。
     * @return
     *      返回查询到的班级id。
     */
    public String getClassId(String className){
        return studentInfoMapper.getClassId(className);
    }
    /**
     * 根据班级id 获取 班级名称、
     *
     * @param classId：班级id。
     * @return
     *      班级名称。
     */
    public String getClassName(String classId){
        return studentInfoMapper.getClassName(classId);
    }

    /**
     * 根据 班级编号，获取成绩表数据的表头课程名信息，
     * @param classId ：班级编号。
     * @return
     */
    public List<String> getCourseNameList(String classId) {
        return studentInfoMapper.getCourseNameList(classId);
    }

    /**
     * 根 据班级名称，获取该班级下的课程id。
     * @param className：班级名
     * @return
     *      获取到的班级id
     */
    public List<String> getCourseIdList(String className){
        return studentInfoMapper.getCourseIdList(className);
    }

    /**
     * 根据 课程号 获取 课程名。
     * @param courseId：获取的课程号。
     * @return
     *      获取的课程名。
     */
    public String getCourseName(String courseId){
        return studentInfoMapper.getCourseName(courseId);
    }
    /**
     * 根据 课程名 获取 课程号。
     * 暂时不考虑课程名前后空格的问题。
     *
     * @param courseName：要查询的课程名。
     * @return
     *      返回查询到的课程号。
     */
    public String getCourseId(String classId,String courseName){
//        classId.substring(0,2)
//        classId.substring(2)
        // 截取数据：24190101 ==》 24
        return studentInfoMapper.getCourseID(classId.substring(0,2),courseName);
    }

    /**
     * 根据传进来的参数进行修改学生成绩信息。
     * @param studentScore：学生成绩信息。
     */
    public void updateStudentScoreInfo(String classId,StudentAndSubjectScore studentScore) {

        // 获取课程名称
        List<String> courseNameList = getCourseNameList(this.getClassId(studentScore.getClassName()));
        System.out.println("课程名：" + Arrays.toString(courseNameList.toArray()));
//        for (int i = 0; i < courseNameList.size(); i++) {
//            String courseId = this.getCourseId(courseNameList.get(i));
//            System.out.println("courseId = " + courseId);
//        }

        List<Object> studentScoreList = studentScore.toList();
        System.out.println("课程分数：" + Arrays.toString(studentScoreList.toArray()));
        // 【小灰漫画算法，java核心技术 1】
        // 【分数1，分数2】



        // 分数赋值。
        for (int i = 0; i < courseNameList.size(); i++) {
            // 查询根据列表遍历进行设置。
            studentInfoMapper.updateStudentScoreInfo(
                    studentScore.getStudentId(),    /*学号*/
                    this.getCourseId(classId,courseNameList.get(i)), /*课程Id*/
                    (Float) studentScoreList.get(3+i)   /*分数*/
            );
        }
    }

    /**
     * 添加学生成绩表信息。
     * @param studentScore：学生成绩表。
     */
    @Transactional
    public Integer addStudentScoreInfo(StudentAndSubjectScore studentScore) {

        // 学号不存在
        if ( !this.isStudentInfo(studentScore.getStudentId()) ){
            System.out.println("学号不存在！请先添加该学生信息。");
            return -1;
        }

        /******************************** 设置 学号，姓名。班级 ********************************/

        // 设置学号
        // 设置姓名
        String studentId = studentScore.getStudentId();
        String studentName = studentScore.getStudentName();

        //

        /******************************** 设置 分数 ********************************/

        // 获取 课程号
        List<String> courseIdList = this.getCourseNameList(this.getClassId(studentScore.getClassName()));
        System.out.println("课程 ID：" + Arrays.toString(courseIdList.toArray()));
        // 获取 课程分数。
        List<Object> studentScoreList = studentScore.toList();
        System.out.println("课程分数：" + Arrays.toString(studentScoreList.toArray()));

        // 获取 班级编号。
//        String classId = this.getClassId(studentScore.getClassName());
//        System.out.println("班级编号：" + classId);

        // 获取 时间
//        new StudentsScoreForOneSubjects("","","",new Date(),0.0F);
        Date date = new Date();




        // 获取 分数

        for (int i = 0; i < courseIdList.size(); i++) {

            // 存在 学号,但 课程号 不存在。
            if ( this.isStudentInfo(studentScore.getStudentId()) && !this.isCourseID(courseIdList.get(i)) ){

                // 添加学生成绩信息。
                studentInfoMapper.addStudentScoreInfo(
                        new StudentsScoreForOneSubjects(
                                studentScore.getStudentId(),
                                courseIdList.get(i),
//                            classId,
                                this.getClassId(studentScore.getClassName()),
                                date,
                                (Float) studentScoreList.get(3+i)
                        )
                );
            }
        }
        // 分数赋值。
//        for (int i = 0; i < courseIdList.size(); i++) {
//            // 查询根据列表遍历进行设置。
//            studentInfoMapper.addStudentScoreInfo(
////                    studentScore.getStudentId(),    /*学号*/
////                    this.getCourseId(courseNameList.get(i)), /*课程Id*/
////                    (Float) studentScoreList.get(3+i)   /*分数*/
//            );
//        }
        return 0;
    }


    /**
     * 根据学号，获取对应的学生姓名。
     * @param studentId：需要查询的学生的学号。
     * @return
     *      返回查询到的学生姓名。
     */
    public String getStudentName(String studentId) {
        return studentInfoMapper.getStudentName(studentId);
    }
}
